package modbus

import (
	"dcs/db"
	"dcs/model"
	"fmt"
	"time"
)

// 将 原始纱锭状态数据 过滤出来， 保存到 cache 中
func InterpretRawDatas(r *model.Base_machine, raw_arr [5]*model.Raw_spindle_status) *SpindleStatus {

	var spindleStatus SpindleStatus
	spindleStatus.Init()

	for _, raw := range raw_arr {

		if raw == nil {
			continue
		}

		length := uint16(len(raw.Raw_data))
		var tail uint16 = 1
		if (length % 2) == 0 {
			tail = 0
		}

		var loop_times uint16 = uint16(length/2) + tail
		if raw.Count < loop_times {
			loop_times = raw.Count
		}

		var position = uint16(raw.Offset) * 4
		var time uint16 = 0
		// 一次移动2个字节 - 对应4个 纱锭
		for ; time < loop_times; time++ {

			val1 := uint16(raw.Raw_data[time*2+1] & 0x0f)
			val2 := uint16((raw.Raw_data[time*2+1] & 0xf0) >> 4)
			val3 := uint16(raw.Raw_data[time*2] & 0x0f)
			val4 := uint16((raw.Raw_data[time*2] & 0xf0) >> 4)

			if (time*2+1) < length && val1 > 0 {
				virtual_index1 := uint16(r.Convert_2_virtual_spin_no(uint(position + 1)))
				spindleStatus.Add(virtual_index1, val1)
			}

			if (time*2+1) < length && val2 > 0 {
				virtual_index2 := uint16(r.Convert_2_virtual_spin_no(uint(position + 2)))
				spindleStatus.Add(virtual_index2, val2)
			}
			if (time*2) < length && val3 > 0 {
				virtual_index3 := uint16(r.Convert_2_virtual_spin_no(uint(position + 3)))
				spindleStatus.Add(virtual_index3, val3)
			}
			if (time*2) < length && val4 > 0 {
				virtual_index4 := uint16(r.Convert_2_virtual_spin_no(uint(position + 4)))
				spindleStatus.Add(virtual_index4, val4)
			}

			position += 4
		}
	}

	return &spindleStatus
}

// SyncSpindleStatus 读取锭子状态， 存入数据库
func SyncSpindleStatus(c *Client, machine *model.Base_machine, offset uint16, count uint16) *model.Raw_spindle_status {

	req := MakeReadSpindleStatusRequest(offset, count)
	c.Conn.Write(req)

	buf := make([]byte, 512)
	n, err := c.Conn.Read(buf)
	if err != nil {
		fmt.Println("read err:", err)
		return nil
	}
	fmt.Println(string(buf[0:n]))

	var raw_spindle_statu = model.Raw_spindle_status{}
	var raw_data []byte = Modbus_decode(buf, n)

	current := time.Now().Format("2006-01-02 15:04:05")

	raw_spindle_statu.Machine_ip = machine.Machine_ip
	raw_spindle_statu.Dtime = current
	raw_spindle_statu.Raw_data = raw_data
	raw_spindle_statu.Offset = offset
	raw_spindle_statu.Count = count

	db.GormDb.Create(&raw_spindle_statu)

	//time.Sleep(time.Millisecond * Interval)

	return &raw_spindle_statu
}

func SyncAllSpindleStatus(c *Client, machine *model.Base_machine) string {
	registers := int(machine.Spindle_count / 4)
	if machine.Spindle_count%4 > 0 {
		registers += 1
	}

	bytes := int(machine.Spindle_count / 2)
	if machine.Spindle_count%2 > 0 {
		bytes += 1
	}

	remainder_bytes := int(bytes % 252)
	remainder_regs := uint16(remainder_bytes/2) + uint16(remainder_bytes%2)
	times := uint16(bytes / 252)
	if remainder_bytes > 0 {
		times += 1
	}

	var offset uint16 = 0
	var index uint16 = 0
	var raw_arr [5]*model.Raw_spindle_status
	for ; index < times; index++ {

		offset += index * 126
		var count uint16 = 126
		if times == index+1 && remainder_bytes > 0 {
			count = remainder_regs
		}
		status := SyncSpindleStatus(c, machine, offset, count)
		raw_arr[index] = status
	}

	return InterpretRawDatas(machine, raw_arr).ToJsonString()
}
